package com.zlh.controller;

import com.zlh.entity.QuartzEntity;
import com.zlh.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @package com.zlh.controller
 * @company: dacheng
 * @author: zlh
 * @createDate: 2022/6/14
 */
@RestController
@RequestMapping("/job")
@Slf4j
public class JobController {
    /**
     * 自动注入scheduler
     */
    @Autowired
    @Qualifier("Scheduler")
    private Scheduler scheduler;

    @PostMapping("/add")
    public Result save(QuartzEntity quartz){
        log.info("新增任务");
        try {
            //如果是修改旧的任务,先删除旧任务，再创建新任务
            if(quartz.getOldJobGroup() != null){
                JobKey key = new JobKey(quartz.getOldJobName(),quartz.getOldJobGroup());
                // 删除一个job
                scheduler.deleteJob(key);
            }
            Class<? extends org.quartz.Job> cls = (Class<? extends Job>) Class.forName(quartz.getJobClassName());
            cls.newInstance();
            //构建job信息
            JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
                    quartz.getJobGroup())
                    .withDescription(quartz.getDescription()).build();
            job.getJobDataMap().put("jobMethodName", quartz.getJobMethodName());
            // 触发时间点
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(quartz.getTriggerName(), quartz.getJobGroup())
                    /**
                     * startNow：将触发器开始的时间设置为当前时刻，
                     * 此时触发器可能会触发，也可能不会触发，具体取决于为触发器配置的计划
                     */
                    .startNow()
                    .withSchedule(cronScheduleBuilder).build();
            //交由Scheduler安排触发
            scheduler.scheduleJob(job, trigger);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/trigger")
    public  Result trigger(QuartzEntity quartz) {
        try {
            JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
            // 触发一个JobDetail(现在执行)
            scheduler.triggerJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/pause")
    public  Result pause(QuartzEntity quartz) {
        log.info("停止任务");
        try {
            JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
            // 根据指定的JobDetail key暂停job。
            scheduler.pauseJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/resume")
    public  Result resume(QuartzEntity quartz) {
        log.info("恢复任务");
        try {
            JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
            // 根据指定的key恢复一个job。
            scheduler.resumeJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    /**
     * 彻底删除任务
     * @param quartz
     * @return
     */
    @PostMapping("/remove")
    public  Result remove(QuartzEntity quartz) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());
            Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
            System.out.println("执行状态："+triggerState.name());
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup()));
            System.out.println("removeJob:"+JobKey.jobKey(quartz.getJobName()));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    /**
     * 更新job表达式和job名称
     * @param quartz
     * @return
     */
    @PostMapping("/reschedule")
    public  Result reschedule(QuartzEntity quartz) {
        try {
            TriggerKey oldTriggerKey = TriggerKey.triggerKey(quartz.getOldJobName(), quartz.getOldJobGroup());
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(oldTriggerKey);
            // 更新表达式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
            // 只替换表达式
//            trigger = trigger.getTriggerBuilder().withIdentity(oldTriggerKey).withSchedule(scheduleBuilder).build();
            trigger = trigger.getTriggerBuilder().withIdentity(quartz.getTriggerName()).withSchedule(scheduleBuilder).build();
            /**
             * 用给定的键删除触发器，并存储新的触发器，它必须与同一个作业相关联（新旧触发器的作业名和组相同）
             * 但是，新旧触发器的名称可以不同。
             */
            scheduler.rescheduleJob(oldTriggerKey,trigger);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    /**
     * 简单定时延迟任务SimpleTrigger
     * @return
     */
    @GetMapping("/simple")
    public  Result simple() {
        try {
            // 定义一个Trigger
            Trigger trigger = TriggerBuilder.newTrigger()
                    // 定义 trigger name/group
                    .withIdentity("Trigger_HelloQuartz", "group1")
                    //一旦加入scheduler，立即执行
                    // .startNow()
                    // 5秒后执行
                    .startAt(new Date(System.currentTimeMillis() + 5000))
                    // 使用SimpleTrigger
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            // 每隔2秒执行一次
                            .withIntervalInSeconds(2)
                            // 重复1次,共计2次
                            .withRepeatCount(1))
                    // 一直执行
                    // .repeatForever())
                    .build();

            // 定义一个JobDetail，定义Job类为JobHelloQuartz
            JobDetail job = JobBuilder.newJob()
                    // 定义job name/group
                    .withIdentity("helloJob", "group1")
                    // 定义属性
                    .usingJobData("name", "Leytton")
                    .build();

            // 加入这个调度
            scheduler.scheduleJob(job, trigger);

            // 启动
            scheduler.start();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            System.out.println("Quartz start at " + sdf.format(new Date()));
            // 运行一段时间后关闭
             Thread.sleep(10000);
             scheduler.shutdown(true);
        } catch (SchedulerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return Result.ok();
    }
}
